package test
{
	import away3d.animators.SkeletonAnimationSet;
	import away3d.animators.SkeletonAnimationState;
	import away3d.animators.SkeletonAnimator;
	import away3d.animators.data.Skeleton;
	import away3d.animators.transitions.CrossfadeStateTransition;
	import away3d.containers.View3D;
	import away3d.entities.Mesh;
	import away3d.events.AssetEvent;
	import away3d.events.LoaderEvent;
	import away3d.library.AssetLibrary;
	import away3d.loaders.parsers.AWD2Parser;
	
	import flash.display.Sprite;
	import flash.events.KeyboardEvent;
	import flash.net.URLRequest;
	import flash.ui.Keyboard;
	
	[SWF(width="1280", height="720", backgroundColor="0x000000")]
	
	public class ActionTest extends Sprite
	{
		public var view:View3D;
		
		private var hero:Mesh;
		
		//animation variables
		private var skeleton:Skeleton;
		private var animationSet:SkeletonAnimationSet;
		private var animator:SkeletonAnimator;
		private var breatheState:SkeletonAnimationState;
		private var walkState:SkeletonAnimationState;
		private var runState:SkeletonAnimationState;
		private var crossfadeTransition:CrossfadeStateTransition;
		private var isRunning:Boolean;
		private var isMoving:Boolean;
		private var movementDirection:Number;
		private var currentAnim:String;
		private var currentRotationInc:Number = 0;
		
		//animation constants
		private const ANIM_BREATHE:String = "Breathe";
		private const ANIM_WALK:String = "Walk";
		private const ANIM_RUN:String = "Run";
		private const XFADE_TIME:Number = 0.5;
		private const ROTATION_SPEED:Number = 3;
		private const RUN_SPEED:Number = 2;
		private const WALK_SPEED:Number = 1;
		private const BREATHE_SPEED:Number = 1;
		
		public function ActionTest()
		{
			super();
			
			AssetLibrary.enableParser(AWD2Parser);
//			AssetLibrary.addEventListener(AssetEvent.ASSET_COMPLETE, onAssetComplete);
			AssetLibrary.addEventListener(LoaderEvent.RESOURCE_COMPLETE, onResourceComplete);
//			AssetLibrary.addEventListener(LoaderEvent.LOAD_ERROR, onLoadError);
			AssetLibrary.load(new URLRequest("../asset/max/test/MaxAWDWorkflow.awd"));
			
			view = new DebugView();
			addChild(view);
		}
		
		private function onResourceComplete(ev:LoaderEvent):void {

			hero = Mesh(AssetLibrary.getAsset("ONKBA-Corps-lnew"));
//			hero.scale(8);
//			hero.z = 1000;
			hero.rotationY = -45;
			//			_human.x = 100;
//			hero.x = 0;
//			hero.y = 100;
//			hero.z = 100;
			view.scene.addChild(hero);
			
			skeleton = Skeleton(AssetLibrary.getAsset("Bone001"));
			breatheState = SkeletonAnimationState(AssetLibrary.getAsset("Breathe"));
			walkState = SkeletonAnimationState(AssetLibrary.getAsset("Walk"));
			runState = SkeletonAnimationState(AssetLibrary.getAsset("Run"));
			
			// Create an animation set object and add our state objects
			animationSet = new SkeletonAnimationSet(3);
			animationSet.addState(breatheState.name, breatheState);
			animationSet.addState(walkState.name, walkState);
			animationSet.addState(runState.name, runState);
			
			//couple our animation set with our skeleton and wrap in an animator object and apply to our mesh object
			animator = new SkeletonAnimator(animationSet, skeleton);
			animator.updateRootPosition = false;
			hero.animator = animator;
			
			//create our crossfade transition object
			crossfadeTransition = new CrossfadeStateTransition(XFADE_TIME);
			
			goToPauseState();
			initListeners();
		}
		
		/**
		 * Initialise the listeners
		 */
		private function initListeners():void
		{
			// Listen for key presses
			stage.addEventListener(KeyboardEvent.KEY_UP, onKeyUp);
			stage.addEventListener(KeyboardEvent.KEY_DOWN, onKeyDown);
		}
		
		/**
		 * Key down listener for animation
		 */
		private function onKeyDown(event:KeyboardEvent):void
		{
			switch (event.keyCode) {
				case Keyboard.SHIFT:
					isRunning = true;
					if (isMoving)
						updateMovement(movementDirection);
					break;
				case Keyboard.UP:
				case Keyboard.W:
					updateMovement(movementDirection = 1);
					break;
				case Keyboard.DOWN:
				case Keyboard.S:
					updateMovement(movementDirection = -1);
					break;
				case Keyboard.LEFT:
				case Keyboard.A:
					currentRotationInc = -ROTATION_SPEED;
					break;
				case Keyboard.RIGHT:
				case Keyboard.D:
					currentRotationInc = ROTATION_SPEED;
					break;
			}
		}
		
		private function onKeyUp(event:KeyboardEvent):void
		{
			switch (event.keyCode) {
				case Keyboard.SHIFT:
					isRunning = false;
					if (isMoving)
						updateMovement(movementDirection);
					break;
				case Keyboard.UP:
				case Keyboard.W:
				case Keyboard.DOWN:
				case Keyboard.S:
					goToPauseState();
					break;
				case Keyboard.LEFT:
				case Keyboard.A:
				case Keyboard.RIGHT:
				case Keyboard.D:
					currentRotationInc = 0;
					break;
			}
		}
		
		private function goToPauseState():void
		{
			isMoving = false;
			
			//update animator speed
			animator.playbackSpeed = BREATHE_SPEED;
			
			//update animator sequence
			if (currentAnim == ANIM_BREATHE)
				return;
			
			currentAnim = ANIM_BREATHE;
			
			animator.play(currentAnim, crossfadeTransition);
		}
		
		private function updateMovement(dir:Number):void
		{
			isMoving = true;
			
			//update animator speed
			animator.playbackSpeed = dir * (isRunning ? RUN_SPEED : WALK_SPEED);
			
			//update animator sequence
			var anim:String = isRunning ? ANIM_RUN : ANIM_WALK;
			if (currentAnim == anim)
				return;
			
			currentAnim = anim;
			
			animator.play(currentAnim, crossfadeTransition);
		}
		
		
	}
}